﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace MvcEngine.Core.Helpers
{
    /// <summary>
    /// This class is used as an abstraction for session variables. The intention is to make using session variable names
    /// a bit safer, by adding a 'scope' name. The scope can be a component name, a class name or any other name that can define
    /// a scope. The session variable will then only be known inside that scope and will therefore not conflict with any
    /// other session variables elsewhere in the application that happen to have the same name.
    /// </summary>
    public class HttpSessionHelper : IHttpSessionHelper
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="HttpSessionUtil"/> class. 
        /// For obtain <see cref="SiteContext"/> object instance, <see cref="P:Sana.Commerce.Web.HttpSessionUtil.Current"/> should be used.
        /// </summary>
        public HttpSessionHelper()
        {
        }
        /// <summary>
        /// Use this property for every method call.
        /// </summary>
        /// <value>The current.</value>
        protected static IHttpSessionHelper Current
        {
            get { return IoC.Resolve<IHttpSessionHelper>(); }
        }

        /// <summary>
        /// Gets the session value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="scope">The scope.</param>
        /// <param name="key">The key.</param>
        /// <returns>Value. If key does not exists, <see langword="null"/> will be returned.</returns>
        public static T GetValue<T>(string scope, string key)
        {
            return Current.GetSessionValue<T>(scope, key);
        }

        public static T GetValue<T>(string key)
        {
            return Current.GetSessionValue<T>(key);
        }
        /// <summary>
        /// Sets the session value. If key does not exists it will be created, otherwise existing key will be overwritten.
        /// The session should be initialized.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="scope">The scope.</param>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public static void SetValue<T>(string scope, string key, T value)
        {
            Current.SetSessionValue<T>(scope, key, value);
        }

        public static void SetValue<T>(string key, T value)
        {
            Current.SetSessionValue<T>(key, value);
        }

        /// <summary>
        /// Remove the key from session.
        /// </summary>
        /// <param name="scope">The scope.</param>
        /// <param name="key">The key.</param>
        public static void ClearValue(string scope, string key)
        {
            Current.ClearSessionValue(scope, key);
        }

        public static void ClearValue(string key)
        {
            Current.ClearSessionValue(key);
        }

        /// <summary>
        /// Determines whether the specified key in the scope is empty.
        /// </summary>
        /// <param name="scope">The scope.</param>
        /// <param name="key">The key.</param>
        /// <returns>
        ///<c>false</c> if the specified key in scope does not exists or <see langword="null"/> ; otherwise, <c>true</c>.
        /// </returns>
        public static bool IsEmpty(string scope, string key)
        {
            return Current.IsSessionValueEmpty(scope, key);
        }

        public static bool IsEmpty(string key)
        {
            return Current.IsSessionValueEmpty(key);
        }

        /// <summary>
        /// Gets the session value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="scope">The scope.</param>
        /// <param name="key">The key.</param>
        /// <returns>Value. If key does not exists, <see langword="null"/> will be returned.</returns>
        public T GetSessionValue<T>(string scope, string key)
        {
            string keyName = string.Concat(scope, ".", key);
            if (HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session[keyName] != null)
            {
                return (T)HttpContext.Current.Session[keyName];
            }
            return default(T);
        }

        public T GetSessionValue<T>(string key)
        {
            if (HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session[key] != null)
            {
                return (T)HttpContext.Current.Session[key];
            }
            return default(T);
        }

        /// <summary>
        /// Sets the session value. If key does not exists it will be created, otherwise existing key will be overwritten.
        /// The session should be initialized.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="scope">The scope.</param>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public void SetSessionValue<T>(string scope, string key, T value)
        {
            string keyName = string.Concat(scope, ".", key);
            if (HttpContext.Current.Session[keyName] != null)
            {
                HttpContext.Current.Session.Remove(keyName);
            }
            HttpContext.Current.Session.Add(keyName, value);
        }

        public void SetSessionValue<T>(string key, T value)
        {
            if (HttpContext.Current.Session[key] != null)
            {
                HttpContext.Current.Session.Remove(key);
            }
            HttpContext.Current.Session.Add(key, value);
        }

        /// <summary>
        /// Remove the key from session.
        /// </summary>
        /// <param name="scope">The scope.</param>
        /// <param name="key">The key.</param>
        public void ClearSessionValue(string scope, string key)
        {
            string keyName = string.Concat(scope, ".", key);
            if (HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session[keyName] != null)
            {
                HttpContext.Current.Session.Remove(keyName);
            }
        }

        public void ClearSessionValue(string key)
        {
            if (HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session[key] != null)
            {
                HttpContext.Current.Session.Remove(key);
            }
        }

        /// <summary>
        /// Determines whether the specified key in the scope is empty.
        /// </summary>
        /// <param name="scope">The scope.</param>
        /// <param name="key">The key.</param>
        /// <returns>
        ///<c>false</c> if the specified key in scope does not exists or <see langword="null"/> ; otherwise, <c>true</c>.
        /// </returns>
        public bool IsSessionValueEmpty(string scope, string key)
        {
            string keyname = string.Concat(scope, ".", key);
            if (HttpContext.Current != null && HttpContext.Current.Session != null)
            {
                return (HttpContext.Current.Session[keyname] == null);
            }
            return true;
        }

        public bool IsSessionValueEmpty(string key)
        {
            if (HttpContext.Current != null && HttpContext.Current.Session != null)
            {
                return (HttpContext.Current.Session[key] == null);
            }
            return true;
        }
    }
}
